package com.jinsilu.freight.ui.activity;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.location.LocationManager;
import android.text.TextUtils;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.amap.api.location.CoordinateConverter;
import com.amap.api.location.DPoint;
import com.blankj.utilcode.util.BusUtils;
import com.blankj.utilcode.util.ConvertUtils;
import com.blankj.utilcode.util.LogUtils;
import com.hdgq.locationlib.LocationOpenApi;
import com.hdgq.locationlib.entity.ShippingNoteInfo;
import com.hdgq.locationlib.listener.OnResultListener;
import com.hjq.http.EasyHttp;
import com.hjq.http.listener.HttpCallback;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;
import com.jinsilu.freight.aop.DebugLog;
import com.jinsilu.freight.common.MyVBActivity;
import com.jinsilu.freight.databinding.ActivityUploadUnloadingBinding;
import com.jinsilu.freight.helper.CommonHelper;
import com.jinsilu.freight.helper.LocationHelper;
import com.jinsilu.freight.helper.ShowImageHelper;
import com.jinsilu.freight.http.model.HttpData;
import com.jinsilu.freight.http.request.GetLineInfoByIdApi;
import com.jinsilu.freight.http.request.UpdateImageApi;
import com.jinsilu.freight.http.request.UploadUnloadPoundsApi;
import com.jinsilu.freight.http.response.FileBean;
import com.jinsilu.freight.http.response.TmsLineBean;
import com.jinsilu.freight.http.response.WaybillBean;
import com.jinsilu.freight.other.AppConfig;
import com.jinsilu.freight.other.IntentKey;
import com.jinsilu.freight.other.MTLConstants;
import com.jinsilu.freight.ui.fragment.UnfinishedWaybillFragment;

import java.io.File;
import java.util.List;

/**
 * 上传卸车磅单
 *
 * @author yangyang
 * @time 2020-11-16 16:40
 */
public class UploadUnloadingActivity extends MyVBActivity<ActivityUploadUnloadingBinding> {

    private String picUrl;
    private WaybillBean waybillBean;

    private double mLongitude = -1; // 经度
    private double mLatitude = -1; //  纬度
    private String mLocateAddress = ""; // 定位地址

    // 获取线路经纬度
    private DPoint mStartLatLng;
    private DPoint mEndLatLng;
    // 实时定位经纬度
    private DPoint mEndLatLngOnLocation;

    @DebugLog
    public static void start(Context context, WaybillBean waybillBean) {
        Intent intent = new Intent(context, UploadUnloadingActivity.class);
        intent.putExtra(IntentKey.WAYBILL, waybillBean);
        context.startActivity(intent);
    }

    @Override
    protected void initView() {

        setOnClickListener(binding.ivUploadUnloading, binding.tvBtnSave);

        waybillBean = getSerializable(IntentKey.WAYBILL);

        binding.etUnloadingWeight.setOnEditorActionListener((v, actionId, event) -> false);
    }

    @Override
    protected void initData() {

        getLineInfoById(waybillBean.getLineId());

        if (XXPermissions.isGranted(this, new String[]{Permission.ACCESS_FINE_LOCATION, Permission.ACCESS_COARSE_LOCATION})) {
            initLocationSDK();
        } else {
            failedOnLocation();
        }
    }

    private void initLocationSDK() {
        // 自定义定位方法
        LocationHelper.init(this);
        LocationHelper.getCurrentLocation(location -> {
            if (null == location) return;
            mLatitude = location.getLatitude();
            mLongitude = location.getLongitude();
            mLocateAddress = location.getAddress();
        });
    }

    @Override
    public void onConfigurationChanged(@NonNull Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        initLocationSDK();
    }

    @Override
    protected void onResume() {
        super.onResume();
        IntentFilter filter = new IntentFilter(LocationManager.PROVIDERS_CHANGED_ACTION);
        filter.addAction(Intent.ACTION_PROVIDER_CHANGED);
        registerReceiver(gpsSwitchStateReceiver, filter);
    }

    private final BroadcastReceiver gpsSwitchStateReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {

            if (LocationManager.PROVIDERS_CHANGED_ACTION.equals(intent.getAction())) {
                // Make an action or refresh an already managed state.
                LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
                boolean isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
//                boolean isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

                if (isGpsEnabled) {
                    initLocationSDK();
                } else {
                    failedOnLocation();
                }
            }
        }
    };

    private void failedOnLocation() {
        mLatitude = -1;
        mLongitude = -1;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        LocationHelper.destroy();
        unregisterReceiver(gpsSwitchStateReceiver);
    }

    @Override
    public void onClick(View v) {
        if (binding.ivUploadUnloading.equals(v)) { // 上传图片
            startImageSelectActivity(0);
        } else if (binding.tvBtnSave.equals(v)) { // 保存
            if (-1 == mLatitude || mLongitude == -1 || TextUtils.isEmpty(mLocateAddress)) {
                initLocationSDK();
            }
            /**
             * 发货、收货地址经纬度为空
             */
            if (null == mStartLatLng || mEndLatLng == null) {
                toast("请联系货主修改线路的收发货经纬度");
                return;
            }
            /*
             * 运单状态 网货 SDK 100045:运单已结束情况下不再调用上传接口
             */
            if (4 == waybillBean.getWaybillStatus() || 5 == waybillBean.getWaybillStatus() || 6 == waybillBean.getWaybillStatus()) {
                BusUtils.postSticky(HomeActivity.TAG_CANCEL_COUNT_DOWN); // 发送消息取消倒计时上传数据
                saveInfo();
            } else if (!TextUtils.isEmpty(AppConfig.getAppSecurity()) && !TextUtils.isEmpty(AppConfig.getEnterpriseSenderCode())) {
                // 网货SDK所需不为空则初始化
                showDialog();
                stopLocation(waybillBean); // 上传定位SDK成功后调用上传卸车磅单接口
            } else {
                saveInfo();
            }
        }
    }

    /**
     * 网络货运SDK 停止定位上传卸车运单号
     */
    private void stopLocation(WaybillBean waybillBean) {

        CoordinateConverter converter = new CoordinateConverter(UploadUnloadingActivity.this);
        // CoordType.GPS 待转换坐标类型
        converter.from(CoordinateConverter.CoordType.GPS);
        // sourceLatLng待转换坐标点 DPoint类型
        try {
            converter.coord(new DPoint(mLatitude, mLongitude));
            mEndLatLngOnLocation = converter.convert();
            LogUtils.e("GetEnd Convert Result Latitude: ", mEndLatLngOnLocation.getLatitude() + " Longitude: ", mEndLatLngOnLocation.getLongitude());
        } catch (Exception e) {
            LogUtils.e("GetEnd Convert Error ", e.getMessage());
            e.printStackTrace();
        }

        ShippingNoteInfo shippingNoteInfo = new ShippingNoteInfo();
        shippingNoteInfo.setShippingNoteNumber(waybillBean.getWaybillNumber());
        shippingNoteInfo.setSerialNumber(MTLConstants.SERIALNUMBER);
        shippingNoteInfo.setStartCountrySubdivisionCode(waybillBean.getConsignorZoningCode());
        shippingNoteInfo.setEndCountrySubdivisionCode(waybillBean.getConsigneeZoningCode());
        shippingNoteInfo.setStartLongitude(mStartLatLng.getLongitude());
        shippingNoteInfo.setStartLatitude(mStartLatLng.getLatitude());
        shippingNoteInfo.setEndLongitude(mEndLatLngOnLocation.getLongitude());
        shippingNoteInfo.setEndLatitude(mEndLatLngOnLocation.getLatitude());
        shippingNoteInfo.setStartLocationText(waybillBean.getConsignorAddress());
        shippingNoteInfo.setEndLocationText(waybillBean.getConsigneeAddress());
        shippingNoteInfo.setVehicleNumber(waybillBean.getVehicleNumber());
        shippingNoteInfo.setDriverName(waybillBean.getDriverName());

        ShippingNoteInfo[] shippingNoteNumbers = new ShippingNoteInfo[]{shippingNoteInfo};
        LogUtils.e(mLongitude, mLongitude);
        /*
         * context 上下文
         * vehicleNumber 车牌号
         * driverName 司机姓名
         * remark 备注
         * shippingNoteNumbers 运单信息列表
         * listener 结果回调函数
         */
        LocationOpenApi.auth(UploadUnloadingActivity.this, AppConfig.getPackageName(), AppConfig.getAppSecurity(), AppConfig.getEnterpriseSenderCode(), AppConfig.getBuildType(), new OnResultListener() {
            @Override
            public void onFailure(String errorCode, String errorMsg) {
                hideDialog();
                // 失败不能影响自己的业务
                saveInfo();
                LogUtils.e(String.format("监管平台SDK认证错误：ErrorCode%s ErrorMsg%s", errorCode, errorMsg));
            }

            @Override
            public void onSuccess(List<ShippingNoteInfo> list) {
                /*
                 * context 上下文
                 * vehicleNumber 车牌号
                 * driverName 司机姓名
                 * remark 备注
                 * shippingNoteNumbers 运单信息列表
                 * listener 结果回调函数
                 */
                LocationOpenApi.stop(UploadUnloadingActivity.this, waybillBean.getVehicleNumber(), waybillBean.getDriverName(), getRemarks(), shippingNoteNumbers, new OnResultListener() {
                    @Override
                    public void onFailure(String errorCode, String errorMsg) {
                        // 100044 要在主线程调用 restart,不要在 auth 接口的回调方法里嵌套调用。
                        runOnUiThread(() -> {
                            if (errorCode.equals("888884")) {
                                CoordinateConverter converter = new CoordinateConverter(UploadUnloadingActivity.this);
                                // CoordType.GPS 待转换坐标类型
                                converter.from(CoordinateConverter.CoordType.GPS);
                                // sourceLatLng待转换坐标点 DPoint类型
                                try {
                                    converter.coord(new DPoint(mLatitude, mLongitude));
                                    mEndLatLngOnLocation = converter.convert();
                                    LogUtils.e("GetEnd Convert Result Latitude: ", mEndLatLngOnLocation.getLatitude() + " Longitude: ", mEndLatLngOnLocation.getLongitude());
                                } catch (Exception e) {
                                    LogUtils.e("GetEnd Convert Error ", e.getMessage());
                                    e.printStackTrace();
                                }
                                // 换手机场景
                                ShippingNoteInfo shippingNoteInfoRestart = new ShippingNoteInfo();
                                shippingNoteInfoRestart.setShippingNoteNumber(waybillBean.getWaybillNumber());
                                shippingNoteInfoRestart.setSerialNumber(MTLConstants.SERIALNUMBER);
                                shippingNoteInfoRestart.setStartCountrySubdivisionCode(waybillBean.getConsignorZoningCode());
                                shippingNoteInfoRestart.setEndCountrySubdivisionCode(waybillBean.getConsigneeZoningCode());
                                // 调用 restart 接口时传入的起点的经纬度是当时的经纬度，终点经纬度是运单拟送达位置的经纬度。
                                shippingNoteInfoRestart.setStartLongitude(mStartLatLng.getLongitude());
                                shippingNoteInfoRestart.setStartLatitude(mStartLatLng.getLatitude());
                                shippingNoteInfoRestart.setEndLongitude(mEndLatLngOnLocation.getLongitude());
                                shippingNoteInfoRestart.setEndLatitude(mEndLatLngOnLocation.getLatitude());
                                shippingNoteInfoRestart.setStartLocationText(waybillBean.getConsignorAddress());
                                shippingNoteInfoRestart.setEndLocationText(waybillBean.getConsigneeAddress());
                                shippingNoteInfoRestart.setVehicleNumber(waybillBean.getVehicleNumber());
                                shippingNoteInfoRestart.setDriverName(waybillBean.getDriverName());
                                ShippingNoteInfo[] shippingNoteNumbersRestart = new ShippingNoteInfo[]{shippingNoteInfoRestart};
                                LocationOpenApi.restart(UploadUnloadingActivity.this, waybillBean.getVehicleNumber(), waybillBean.getDriverName(), "[02]换手机", shippingNoteNumbersRestart, new OnResultListener() {
                                    @Override
                                    public void onFailure(String s, String s1) {
                                        hideDialog();
                                        // 失败不能影响自己的业务
                                        saveInfo();
                                        LogUtils.e(String.format("监管平台SDK重启错误: ErrorCode%s ErrorMsg%s", errorCode, errorMsg));
                                    }

                                    @Override
                                    public void onSuccess(List<ShippingNoteInfo> list1) {
                                        /*
                                         * context 上下文
                                         * vehicleNumber 车牌号
                                         * driverName 司机姓名
                                         * remark 备注
                                         * shippingNoteNumbers 运单信息列表
                                         * listener 结果回调函数
                                         */
                                        LocationOpenApi.stop(UploadUnloadingActivity.this, waybillBean.getVehicleNumber(), waybillBean.getDriverName(), getRemarks(), shippingNoteNumbersRestart, new OnResultListener() {
                                            @Override
                                            public void onFailure(String errorCode1, String errorMsg1) {
                                                hideDialog();
                                                // 失败不能影响自己的业务
                                                saveInfo();
                                                LogUtils.e(String.format("监管平台SDK结束错误: ErrorCode%s ErrorMsg%s", errorCode1, errorMsg1));
                                            }

                                            @Override
                                            public void onSuccess(List<ShippingNoteInfo> list1) {
                                                hideDialog();
                                                CommonHelper.clearObj("sdk");
                                                BusUtils.postSticky(HomeActivity.TAG_CANCEL_COUNT_DOWN); // 发送消息取消倒计时上传数据
                                                saveInfo();
                                            }
                                        });
                                    }
                                });
                            } else {
                                hideDialog();
                                // 失败不能影响自己的业务
                                saveInfo();
                                LogUtils.e(String.format("监管平台SDK停止错误: ErrorCode%s ErrorMsg%s", errorCode, errorMsg));
                            }
                        });
                    }

                    @Override
                    public void onSuccess(List<ShippingNoteInfo> list) {
                        hideDialog();
                        CommonHelper.clearObj("sdk");
                        BusUtils.postSticky(HomeActivity.TAG_CANCEL_COUNT_DOWN); // 发送消息取消倒计时上传数据
                        saveInfo();
                    }
                });

            }
        });

    }

    /**
     * 01表示实际停止位置与预计不一致的，stop方法时，具体原因需要文字描述
     * 如果收货地址与实际地址大于5公里则需要备注
     * 例子： [01]货主临时改变收货位置
     *
     * @return 备注信息
     */
    private String getRemarks() {
        /**
         * 计算两点间距离 单位：米
         *
         * DPoint(double latitude, double longitude)
         * CoordinateConverter类提供calculateLineDistance(DPoint startLatlng, DPoint endLatlng)接口可以用来判断两坐标点之间的距离。*/
        float distance = CoordinateConverter.calculateLineDistance(mEndLatLngOnLocation, mEndLatLng) * 1000;

        return distance > 5 ? "[01]货主临时改变收货位置" : "";
    }

    public void saveInfo() {
        if (TextUtils.isEmpty(picUrl)) {
            toast("请上传卸车磅单图片");
            return;
        }

        String weight = binding.etUnloadingWeight.getText().toString().trim();
        if (TextUtils.isEmpty(weight)) {
            toast("请输入卸车净重");
            return;
        }

        // 上传装车磅单
        EasyHttp.put(this)
                .api(new UploadUnloadPoundsApi()
                        .setImageUrl(picUrl)
                        .setWeight(weight)
                        .setWaybillNumber(waybillBean.getWaybillNumber())
                        .setUnloadAddress(mLocateAddress)
                        .setLongitude(String.valueOf(mLongitude))
                        .setLatitude(String.valueOf(mLatitude)))
                .request(new HttpCallback<HttpData<Void>>(this) {

                    @Override
                    public void onSucceed(HttpData<Void> data) {
                        toast(data.getMessage());
                        BusUtils.postSticky(UnfinishedWaybillFragment.TAG_NEED_TO_REFRESH_WAYBILL); // UnfinishedWaybillFragment will receive
                        finish();
                        // 网货SDK所需不为空则初始化
//                        if (!TextUtils.isEmpty(AppConfig.getAppSecurity()) && !TextUtils.isEmpty(AppConfig.getEnterpriseSenderCode())) {
//                            showDialog();
//                            stopLocation(waybillBean); // 上传定位SDK成功后调用上传卸车磅单接口
//                        } else {
//                            finish();
//                        }
                    }
                });
    }

    /**
     * 启动图片选择
     */
    private void startImageSelectActivity(int index) {
        ImageSelectVBActivity.start(this, new ImageSelectVBActivity.OnPhotoSelectListener() {

            @Override
            public void onSelected(File file) {
//                File file = CommonHelper.getFileFromUri(data);
                uploadImage(file);
            }

            @Override
            public void onCancel() {
            }
        });
    }

    private void uploadImage(File file) {
        // 上传文件
        EasyHttp.post(this)
                .api(new UpdateImageApi()
                        .setImage(file))
                .request(new HttpCallback<HttpData<FileBean>>(this) {

                    @Override
                    public void onSucceed(HttpData<FileBean> data) {
//                        FileUtils.delete(file);
                        String imgUrl = data.getData().getUrl();
                        picUrl = imgUrl;
                        ShowImageHelper.showNormal(UploadUnloadingActivity.this, imgUrl, binding.ivUploadUnloading);
                    }
                });
    }

    /**
     * 通过线路id获取线路信息
     *
     * @param lineId 线路ID
     */
    private void getLineInfoById(String lineId) {
        // 上传文件
        EasyHttp.get(this)
                .api(new GetLineInfoByIdApi()
                        .setLineId(lineId))
                .request(new HttpCallback<HttpData<TmsLineBean>>(this) {

                    @Override
                    public void onSucceed(HttpData<TmsLineBean> data) {
                        TmsLineBean tmsLineBean = data.getData();
                        if (0.0 == tmsLineBean.getStartLatitude() || 0.0 == tmsLineBean.getStartLongitude()
                                || 0.0 == tmsLineBean.getEndLatitude() || 0.0 == tmsLineBean.getEndLongitude()) {
                            mStartLatLng = null;
                            mEndLatLng = null;
                        } else {
                            CoordinateConverter converter = new CoordinateConverter(UploadUnloadingActivity.this);
                            // CoordType.GPS 待转换坐标类型
                            converter.from(CoordinateConverter.CoordType.GPS);
                            // sourceLatLng待转换坐标点 DPoint类型
                            // DPoint(double latitude, double longitude)
                            try {
                                converter.coord(new DPoint(tmsLineBean.getStartLatitude(), tmsLineBean.getStartLongitude()));
                                mStartLatLng = converter.convert();
                                converter.coord(new DPoint(tmsLineBean.getEndLatitude(), tmsLineBean.getEndLongitude()));
                                mEndLatLng = converter.convert();
                                LogUtils.e("GetStart Convert Result Latitude: ", mStartLatLng.getLatitude() + " Longitude: ", mStartLatLng.getLongitude());
                                LogUtils.e("GetEnd Convert Result Latitude: ", mEndLatLng.getLatitude() + " Longitude: ", mEndLatLng.getLongitude());
                            } catch (Exception e) {
                                LogUtils.e("GetEnd Convert Error ", e.getMessage());
                                e.printStackTrace();
                            }
                        }
                    }
                });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == XXPermissions.REQUEST_CODE) {
            if (XXPermissions.isGranted(this,new String[]{
                    Permission.ACCESS_FINE_LOCATION,
                    Permission.ACCESS_COARSE_LOCATION})) {
                toast("用户已经在权限设置页授予定位权限");
            } else {
                toast("用户没有在权限设置页授予权限");
            }
        }
    }
}
